package com.inifitness.tenant.core.system.service.impl;


import java.util.Arrays;
import java.util.List;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.inifitness.common.model.Option;
import com.inifitness.tenant.core.system.converter.DictConverter;
import com.inifitness.tenant.core.system.mapper.SysDictMapper;
import com.inifitness.tenant.core.system.model.entity.SysDict;
import com.inifitness.tenant.core.system.model.entity.SysDictItem;
import com.inifitness.tenant.core.system.model.form.DictForm;
import com.inifitness.tenant.core.system.model.query.DictPageQuery;
import com.inifitness.tenant.core.system.model.vo.DictPageVO;
import com.inifitness.tenant.core.system.service.SysDictItemService;
import com.inifitness.tenant.core.system.service.SysDictService;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.text.CharSequenceUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 数据字典类型业务实现类
 *
 * @author sunjinfeng
 * @since 2024/04/18 11:00:00
 */
@Service
@RequiredArgsConstructor
public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> implements
    SysDictService {


  private final SysDictItemService dictItemService;
  private final DictConverter dictConverter;

  /**
   * 字典分页列表
   *
   * @param queryParams 分页查询对象
   * @return
   */
  @Override
  public Page<DictPageVO> getDictPage(DictPageQuery queryParams) {
    // 查询参数
    int pageNum = queryParams.getPageNum();
    int pageSize = queryParams.getPageSize();
    String keywords = queryParams.getKeywords();

    // 查询数据
    Page<SysDict> dictTypePage = this.page(
        new Page<>(pageNum, pageSize),
        new LambdaQueryWrapper<SysDict>()
            .like(CharSequenceUtil.isNotBlank(keywords), SysDict::getName, keywords)
            .or()
            .like(CharSequenceUtil.isNotBlank(keywords), SysDict::getCode, keywords)
            .select(
                SysDict::getId,
                SysDict::getName,
                SysDict::getCode,
                SysDict::getStatus,
                SysDict::getRemark
            )
    );

    // 实体转换
    Page<DictPageVO> pageResult = dictConverter.entity2Page(dictTypePage);
    return pageResult;
  }

  /**
   * 获取字典类型表单详情
   *
   * @param id 字典类型ID
   * @return
   */
  @Override
  public DictForm getDictForm(Long id) {
    // 获取entity
    SysDict entity = this.getOne(new LambdaQueryWrapper<SysDict>()
        .eq(SysDict::getId, id)
        .select(
            SysDict::getId,
            SysDict::getName,
            SysDict::getCode,
            SysDict::getStatus,
            SysDict::getRemark
        ));
    Assert.isTrue(entity != null, "字典类型不存在");

    // 实体转换
    DictForm dictForm = dictConverter.entity2Form(entity);
    return dictForm;
  }

  /**
   * 新增字典类型
   *
   * @param dictForm
   * @return
   */
  @Override
  public boolean saveDict(DictForm dictForm) {
    // 实体对象转换 form->entity
    SysDict entity = dictConverter.form2Entity(dictForm);
    // 持久化
    boolean result = this.save(entity);
    return result;
  }


  /**
   * 修改字典类型
   *
   * @param id       字典类型ID
   * @param dictForm 字典类型表单
   * @return
   */
  @Override
  public boolean updateDict(Long id, DictForm dictForm) {
    // 获取字典类型
    SysDict sysDict = this.getById(id);
    Assert.isTrue(sysDict != null, "字典类型不存在");

    SysDict entity = dictConverter.form2Entity(dictForm);
    boolean result = this.updateById(entity);
    if (result) {
      // 字典类型code变化，同步修改字典项的类型code
      String oldCode = sysDict.getCode();
      String newCode = dictForm.getCode();
      if (!CharSequenceUtil.equals(oldCode, newCode)) {
        dictItemService.update(new LambdaUpdateWrapper<SysDictItem>()
            .eq(SysDictItem::getTypeCode, oldCode)
            .set(SysDictItem::getTypeCode, newCode)
        );
      }
    }
    return result;
  }

  /**
   * 删除字典类型
   *
   * @param idsStr 字典类型ID，多个以英文逗号(,)分割
   * @return
   */
  @Override
  @Transactional
  public boolean deleteDicts(String idsStr) {

    Assert.isTrue(CharSequenceUtil.isNotBlank(idsStr), "删除数据为空");

    List ids = Arrays.asList(idsStr.split(","))
        .stream()
        .toList();

    // 删除字典数据项
    List<String> dictTypeCodes = this.list(new LambdaQueryWrapper<SysDict>()
            .in(SysDict::getId, ids)
            .select(SysDict::getCode))
        .stream()
        .map(SysDict::getCode)
        .toList();
    if (CollUtil.isNotEmpty(dictTypeCodes)) {
      dictItemService.remove(new LambdaQueryWrapper<SysDictItem>()
          .in(SysDictItem::getTypeCode, dictTypeCodes));
    }
    // 删除字典类型
    boolean result = this.removeByIds(ids);
    return result;
  }

  /**
   * 获取字典类型的数据项
   *
   * @param typeCode
   * @return
   */
  @Override
  public List<Option> listDictItemsByDictCode(String typeCode) {
    // 数据字典项
    List<SysDictItem> dictItems = dictItemService.list(new LambdaQueryWrapper<SysDictItem>()
        .eq(SysDictItem::getTypeCode, typeCode)
        .select(SysDictItem::getValue, SysDictItem::getName)
    );

    // 转换下拉数据
    List<Option> options = CollUtil.emptyIfNull(dictItems)
        .stream()
        .map(dictItem -> new Option(dictItem.getValue(), dictItem.getName()))
        .toList();
    return options;
  }


}




